﻿using System.Collections.Generic;
using LightWeb.Infrastructure.Repositories;
using FlyearAssist.Hibernating.DataModel;
using LightWeb.Infrastructure.DomainModel;

namespace LightWeb.DomainModel.Security
{
    public class Service
    {
        public void CreateUser(User model)
        {
            using (OurTransactionScope ts = new OurTransactionScope())
            {
                var context = DataContext.Current;

                var existsModel = context.Read<User>(new List<NCondition> { new NCondition { PropertyName = "LoginName", Operate = Operation.EQ, PropertyValue = model.LoginName } }, null);
                if (existsModel != null) throw new ExistsSameEntityException(typeof(User)) { KeyName = "LoginName", KeyValue = model.LoginName };

                context.Persist(model);
                ts.Complete();
            }
        }
        public bool ValidateUser(User model)
        {
            DataContext dc = new DataContext();
            User user = null;
            if (!string.IsNullOrWhiteSpace(model.Email))
                user = dc.FindByProperty<User>(new List<string> { "Email", "Password" }.ToArray(), new List<string> { model.LoginName, model.Password }.ToArray());
            if (!string.IsNullOrWhiteSpace(model.LoginName))
                user = dc.FindByProperty<User>(new List<string> { "LoginName", "Password" }.ToArray(), new List<string> { model.LoginName, model.Password }.ToArray());
            return user != null;
        }

        public IList<Role> GetAllRoles()
        {
            DataContext dc = new DataContext();
            return dc.Read<Role>(null, null);
        }

        public IList<Role> GetRolesForUser(string username)
        {
            DataContext dc = new DataContext();
            return dc.Read<Role>(new List<NCondition> { new NCondition { PropertyName = "Users.LoginName", Operate = Operation.EQ, PropertyValue = username } }, null);
        }

        public IList<User> GetUsersInRole(string roleName)
        {
            DataContext dc = new DataContext();
            return dc.Read<User>(new List<NCondition> { new NCondition { PropertyName = "Roles.RoleName", Operate = Operation.EQ, PropertyValue = roleName } }, null);
        }

        public bool IsUserInRole(string username, string roleName)
        {
            DataContext dc = new DataContext();
            List<NCondition> whereConditionList = new List<NCondition>();
            whereConditionList.Add(new NCondition { PropertyName = "LoginName", Operate = Operation.EQ, PropertyValue = username });
            whereConditionList.Add(new NCondition { PropertyName = "Roles.RoleName", Operate = Operation.EQ, PropertyValue = roleName });
            return dc.Read<User>(whereConditionList, null) == null;
        }

        public bool RoleExists(string roleName)
        {
            DataContext dc = new DataContext();
            List<NCondition> whereConditionList = new List<NCondition>();
            whereConditionList.Add(new NCondition { PropertyName = "Name", Operate = Operation.EQ, PropertyValue = roleName });
            return dc.Read<Role>(whereConditionList, null) == null;
        }

        public bool RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new System.NotImplementedException();
        }

        public void CreateRole(string roleName)
        {
            using (OurTransactionScope ts = new OurTransactionScope())
            {
                var context = DataContext.Current;

                var existsModel = context.Read<Role>(new List<NCondition> { new NCondition { PropertyName = "Name", Operate = Operation.EQ, PropertyValue = roleName } }, null);
                if (existsModel != null) throw new ExistsSameEntityException(typeof(Role)) { KeyName = "Name", KeyValue = roleName };
                context.Persist(new Role { Name = roleName });
                ts.Complete();
            }
        }

        public bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            using (OurTransactionScope ts = new OurTransactionScope())
            {
                var context = DataContext.Current;

                context.Delete(new Role { Name = roleName });
                ts.Complete();
            }
            return true;
        }

        public IList<Role> GetUsersInRole(string roleName, string usernameToMatch)
        {
            throw new System.NotImplementedException();
        }

        public void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new System.NotImplementedException();
        }
    }
}
